package com.han.verifycode.ver;

import com.han.verifycode.CodeConfig;
import com.han.verifycode.VerifyCode;
import com.han.verifycode.data.Answer;
import com.han.verifycode.data.Area;
import com.han.verifycode.data.Position;
import com.han.verifycode.data.RightKey;
import com.han.verifycode.data.area.RectangleArea;
import com.han.verifycode.enums.VerifyCodeEnum;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 点位范围
 */
public interface PointAreaMatchCode extends VerifyCode {
    @Override
    default boolean verify(RightKey righKey, Answer answer) {
        CodeConfig config = righKey.getConfig();
        Integer baseWidth = config.getWidth();
        Integer targetWidth = answer.getWidth();
        //所有的target 位置都要乘以这个比例
        double rate = (double) baseWidth / (double) targetWidth;
        List<Area> areas = righKey.getPositions();
        List<Position> targetPositions = answer.getPositions().stream().map(v -> new Position((int) (v.getX() * rate), (int) (v.getY() * rate))).collect(Collectors.toList());
        //先把数量对上
        if (areas.size() != targetPositions.size()) {
            return false;
        }
        if (righKey.getType() == VerifyCodeEnum.IdiomPoint) {
            //成语多点识别要考虑顺序

            for (int i = 0; i < areas.size(); i++) {
                Area area = areas.get(i);
                Position p = targetPositions.get(i);
                boolean isIn = area.verifyPosition(p);
                if (!isIn) {
                    return false;
                }
            }
            return true;
        }
        if (righKey.getType() == VerifyCodeEnum.PicturePoint) {
            //图片点选 不需要考虑顺序 能匹配到即可
            //先对这些点和区域进行排序
            List<Area> sAreas = areas.stream().sorted((v1, v2) -> {
                RectangleArea rv1 = (RectangleArea) v1;
                RectangleArea rv2 = (RectangleArea) v2;
                Position p11 = rv1.getP1();
                Position p21 = rv2.getP1();
                return p11.compareTo(p21);
            }).collect(Collectors.toList());

            List<Position> sPs = targetPositions.stream().sorted(Position::compareTo).collect(Collectors.toList());
            for (int i = 0; i < sAreas.size(); i++) {
                Area area = sAreas.get(i);
                Position p = sPs.get(i);
                boolean isIn = area.verifyPosition(p);
                if (!isIn) {
                    return false;
                }
            }
            return true;
        }
        if (righKey.getType() == VerifyCodeEnum.PicturePuzzle) {
            //横向拼图 只比较x  允许误差（Area 直接是一个算好误差的范围）
            Area area = areas.get(0);
            Position p = answer.getPositions().get(0);
            RectangleArea rv1 = (RectangleArea) area;
            Integer xMin = rv1.getP1().getX();
            Integer xMax = rv1.getP2().getX();
            return p.getX() >= xMin && p.getX() <= xMax;
        }
        return false;
    }
}
